package com.hitqz.robot.api.dispatch.protocol;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.hitqz.robot.api.business.dto.FileChunkDto;
import com.hitqz.robot.api.business.dto.RobotClientSummaryDto;
import com.hitqz.robot.api.business.dto.RobotControlButtonDto;
import com.hitqz.robot.api.dispatch.model.MessageDto;
import com.hitqz.robot.api.dispatch.protocol.dto.*;
import com.hitqz.robot.camera.dto.RealManArmMoveDto;
import com.hitqz.robot.camera.dto.RealManArmStateDto;
import com.hitqz.robot.common.core.util.R;
import lombok.Getter;
import org.apache.poi.ss.formula.functions.T;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Objects;

public enum ProtocolEnum {

	/************************************0 通用返回状态*************************************************************************************************/

	RESULT(0,"通用返回", R.class),

	ROBOT_REGISTER(999, "机器人上线后发送注册", RobotRegisterDto.class),

	MODIFY_SYS_INF(1999, "修改系统信息", ModifySysInfoDto.class),

	UPLOAD_LOG_FILE(2999, "上传日志文件", UploaderLogFileDto.class),

	REPORT_LOG_MESSAGE(3000, "上传日志", ReportLogMessageDto.class),

	REPORT_BATTERY(3010, "上传电量数据", ReportBatteryLevelDto.class),


	/************************************10000-19999 状态查询或主动上传*********************************************************************************/

	//todo 机器人信息暂时没定

	ROBOT_SUMMARY(10000,"机器人基本情况", RobotClientSummaryDto.class),

	ROBOT_MAP_INFO(10001,"机器人地图信息", RobotMapDto.class),

	ROBOT_AREA_INFO(10002,"机器人地图区域信息", RobotMapAreaDto.class),

	ROBOT_INFO (10003, "机器人信息",  RobotDto.class),

	ROBOT_MAP_POS_INFO(10004,"机器人地图点位信息", RobotMapPosDto.class),

	ROBOT_TICKETS(10005, "机器人工单信息", RobotTicketsDto.class),

	ROBOT_WARNING(10006, "机器人告警信息", RobotWarningDto.class),

	TASK_CONTENT(10010, "动态任务内容", FormConfigModalDto.class),

	FILE_UPLOAD(10011,"文件上传", FileChunkDto.class),


	/************************************20000-29999 为机器人控制****************************************************************************************/

	ROBOT_CTRL_CMD(21000, "机器人控制(通用)", RobotControlButtonDto.class),

	ROBOT_NAV_CMD(21001, "机器人导航状态控制", RobotCmdNavDto.class),

	ROBOT_NAV_POS_CMD(21004, "机器人前往目标站点", CmdRobot2PosDto.class),

	/************************************30000-39999 为外设控制*****************************************************************************************/

	ROBOT_REAL_MAN_ARM_STATUS(30000, "瑞尔曼机械臂状态", RealManArmStateDto.class),
	ROBOT_REAL_MAN_ARM_SET_ZERO_POINT(30001, "瑞尔曼机械臂设置零点", RealManArmStateDto.class),
	ROBOT_REAL_MAN_ARM_TURN_ZERO_POINT(30002, "瑞尔曼机械臂转向零点", RealManArmStateDto.class),
	ROBOT_REAL_MAN_ARM_RECOVERY(30003, "瑞尔曼机械臂急停恢复", RealManArmStateDto.class),
	ROBOT_REAL_MAN_ARM_MOVE(30004, "瑞尔曼机械臂关节运动", RealManArmMoveDto.class),





	/************************************40000-49999 为视觉调用*****************************************************************************************/




	/************************************4000-4999 调度命令*****************************************************************************************/

	ROBOT_CMD_AVOID_POS(4000, "调度系统-前往避让点", RobotApplyPathDto.class),

	ROBOT_APPLY_TARGET_POS(4110, "申请路径", RobotApplyPathDto.class),

	ROBOT_FINISH_POS(4111, "上报完成的点", RobotFinishPosDto.class),

	ROBOT_CMD_TICKETS(4050, "下发机器人任务", RobotCmdTicketsDto.class),

	CMD_NEXT_STEP(4060, "下发给机器人执行下一步", RobotNextStepDto.class),

	ROBOT_DISPATCH_CMD(4070, "调度上下线", RobotDispatchCmdDto.class),


	/************************************ 1-机器人同步命令*****************************************************************************************/

	// 具体的同步消息 为所传的dto里面cmd 字段来决定
	ROBOT_SYNC_CMD(1, "机器人下发同步命令",  R.class),





	;


	public final static HashMap<Short,ProtocolEnum> CMD_PROTOCOL_MAP = new HashMap<>();



	static {
		for (ProtocolEnum value: values()) {
			ProtocolEnum.CMD_PROTOCOL_MAP.put(value.getCmd(), value);
		}
	}

	//命令号
	@Getter
	private final short cmd;
	//描述
	@Getter
	private final String description;

	@Getter
	private final Class<?> clazz;


	ProtocolEnum(Integer cmd, String description, Class<?> clazz) {
		this.cmd = cmd.shortValue();
		this.description = description;
		this.clazz = clazz ;
	}

	// 根据实体类获取命令号
	public static Short getCmdByClass(Class<?> clazz){
		for (ProtocolEnum value : ProtocolEnum.CMD_PROTOCOL_MAP.values()) {
			if(Objects.equals(value.getClazz(), clazz)){
				return value.cmd;
			}
		}
		return null;
	}

	public static MessageDto getMessage(T obj){
		Short cmd = getCmdByClass(obj.getClass());
		int sn = Integer.parseInt(DateUtil.format(new Date(),"yyyyMMddHHmmssSSS"));
		String jsonString = JSON.toJSONString(obj);
		MessageDto messageDto = new MessageDto();
		messageDto.setSn(sn);
		messageDto.setCmd(cmd);
		messageDto.setData(jsonString.getBytes(StandardCharsets.UTF_8));
		messageDto.setDataLength(jsonString.getBytes(StandardCharsets.UTF_8).length);
		return messageDto;
	}


}
